﻿using npljobs.JobAlertService.Objects;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace npljobs.JobAlertService.Helper
{
    public enum Frequency
    {
        Daily,
        Weekly,
        Monthly
    }

    /// <summary>
    /// This class is used to process jobs based on the alert set by the user
    /// </summary>
    public class CreateAlertJob
    {
        #region SendJobs
        public string SendJobs()
        {
            string htmlBody = string.Empty;

            try
            {
                DataSet dsJobSeekerJobAlert = new DataSet();
                DBHepler dbHelper = new DBHepler();
                dsJobSeekerJobAlert = dbHelper.GetJobSeekerAlert();

                DateTime lastUpdate = DateTime.MinValue;

                if (dsJobSeekerJobAlert != null)
                {
                    foreach (DataRow dr in dsJobSeekerJobAlert.Tables[0].Rows)
                    {
                        Guid jobSeekerID = dr["JobSeekerID"] != null ? Guid.Parse(dr["JobSeekerID"].ToString()) : Guid.Empty;
                        string frequency = dr["Frequency"] != null ? dr["Frequency"].ToString() : string.Empty;
                        int frequencyID = dr["FrequencyID"] != null ? int.Parse(dr["FrequencyID"].ToString()) : -1;
                        int jobAlertID = dr["JobAlertID"] != null ? int.Parse(dr["JobAlertID"].ToString()) : -1;
                        int cityID = dr["CityID"] != null ? int.Parse(dr["CityID"].ToString()) : -1;
                        int countryID = dr["CountryID"] != null ? int.Parse(dr["CountryID"].ToString()) : -1;
                        int categoryID = dr["CategoryID"] != null ? int.Parse(dr["CategoryID"].ToString()) : -1;
                        int jobTypeID = dr["WorkTypeID"] != null ? int.Parse(dr["WorkTypeID"].ToString()) : -1;
                        int salaryID = dr["SalaryRangeID"] != null ? int.Parse(dr["SalaryRangeID"].ToString()) : -1;
                        string jobTitle = dr["JobTitle"] != null ? dr["JobTitle"].ToString().Trim() : string.Empty;
                        string allSkills = dr["Skill"] != null ? dr["Skill"].ToString() : string.Empty;

                        DataSet dsJobAlertStatus = dbHelper.GetJobAlertStatus(jobSeekerID, jobAlertID, frequencyID);

                        if (dsJobAlertStatus.Tables[0].Rows.Count > 0)
                        {
                            bool b = DateTime.TryParse(dsJobAlertStatus.Tables[0].Rows[0][0].ToString(), out lastUpdate);
                        }
                        //if (!CheckAlertStatus(jobSeekerID, jobAlertID, frequencyID))
                        //{
                        if (ProcessJobAndSendMail(htmlBody, jobSeekerID, allSkills, lastUpdate, frequencyID, cityID, countryID, categoryID, jobTypeID, salaryID, jobTitle, jobAlertID))
                        {
                            SaveJobSeekerAlertStatus(jobSeekerID, jobAlertID, frequencyID);
                        }
                        //}
                        //else
                        //{
                        //    ProcessJobAndSendMail(htmlBody, jobSeekerID, allSkills, dtStatus, frequencyID);
                        //}
                    }
                }
            }
            catch (Exception ex)
            {
            }

            return htmlBody;
        }


        #endregion

        #region SaveJobSeekerAlertStatus
        private void SaveJobSeekerAlertStatus(Guid jobSeekerID, int jobAlertID, int frequencyID)
        {
            DBHepler dbHelper = new DBHepler();

            try
            {
                dbHelper.SaveJobSeekerAlertStatus(jobSeekerID, jobAlertID, frequencyID);
            }
            catch (Exception)
            {
            }
        }
        #endregion

        #region CheckAlertStatus
        private bool CheckAlertStatus(Guid jobSeekerID, int jobAlertID, int frequencyID)
        {
            bool isExists = false;

            DBHepler dbHelper = new DBHepler();
            try
            {
                isExists = dbHelper.CheckAlertStatus(jobSeekerID, jobAlertID, frequencyID);

            }
            catch (Exception)
            {
                isExists = false;
            }

            return isExists;
        }
        #endregion

        #region ProcessJobAndSendMail
        private bool ProcessJobAndSendMail(string htmlBody, Guid jobSeekerID, string allSkills, DateTime lastUpdate, int frequencyID,
            int cityID, int countryID, int categoryID, int jobTypeID, int salaryID, string jobTitle, int jobAlertID)
        {
            DBHepler dbHelper = new DBHepler();

            bool isSentMail = false;
            try
            {
                if (!string.IsNullOrEmpty(allSkills))
                {
                    string[] skills = allSkills.Split(new char[] { ',' });

                    DataTable dtSkill = new DataTable();
                    dtSkill.Columns.Add("Skill", typeof(string));
                    dtSkill.NewRow();

                    List<string> ids = new List<string>();
                    string id = string.Empty;

                    for (int i = 0; i < skills.Count(); i++)
                    {
                        string s = skills[i].ToString();
                        if (s != null)
                        {
                            dtSkill.Rows.Add(s);
                        }
                    }

                    List<Job> lstJobs = dbHelper.GetJobs(dtSkill, cityID, countryID, categoryID, jobTypeID, salaryID, jobTitle);
                    JobSeeker jobSeeker = dbHelper.GetJobSeekerById(jobSeekerID);

                    if (jobSeeker != null)
                    {
                        if (lstJobs.Count > 0)
                        {
                            htmlBody = CreateHtmlBody(jobSeeker, lstJobs, allSkills, jobAlertID);
                            string sendTo = jobSeeker.Email;

                            SendMail sendmail = new SendMail();

                            if (lastUpdate == DateTime.MinValue)
                            {
                                isSentMail = sendmail.SendEMail(sendTo, htmlBody);
                            }
                            else
                            {
                                if (HasSpecifiedTimeElapsed(lastUpdate, frequencyID))
                                    isSentMail = sendmail.SendEMail(sendTo, htmlBody);
                            }

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                isSentMail = false;
            }

            return isSentMail;
        }
        #endregion

        #region CreateHtmlBody
        private string CreateHtmlBody(JobSeeker jobSeeker, List<Job> lstJobs, string skills, int JobAlertID)
        {
            StringBuilder sb = new StringBuilder();
            string htmlBody = string.Empty;
            StringBuilder jobList = new StringBuilder();

            try
            {
                for (int i = 0; i < lstJobs.Count && i < 10; i++)
                {
                    jobList.AppendFormat("<li><a href='http://www.npljobs.com/JobSeeker/JobDetails.aspx?jID={0}' target='_blank' ><span ><strong><span style='font-size: 12px;'>{1}</span></strong></span></a></li>", lstJobs[i].JobID.ToString(), lstJobs[i].JobTitle);
                }

                if (lstJobs.Count > 10)
                {
                    jobList.Append("<li><span><strong>............</span></strong><a href='http://www.npljobs.com/Job/CategoryWiseJobSearch.aspx' ><span style='color: rgb(79, 129, 189);'><strong><span style='font-size: 12px;'>Show more</span></strong></span></a></li>");
                }

                sb.AppendFormat("<a href='www.npljobs.com/Unsubscribe.aspx?JobSeekerID={0}{1}'>click here to unsubscribe</a>.", jobSeeker.JobSeekerID.ToString());

                htmlBody = PopulateBody(jobSeeker.FirstName + " " + jobSeeker.LastName, skills, jobList.ToString(), PrepareJObsList(lstJobs), lstJobs.Count, jobSeeker.PostalAddress, sb.ToString());

            }
            catch (Exception ex)
            {
                throw ex;
            }
            return htmlBody;
        }

        private string PrepareJObsList(List<Job> lstJobs)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < lstJobs.Count && i < 10; i++)
            {

                sb.Append("<div class='movableContent' style='border: 0px; padding-top: 0px;'>");
                sb.Append("<div>");
                sb.Append("<table cellpadding='0' cellspacing='0' border='0' style='margin-top: 10px;'>");
                sb.Append("<tbody><tr><td valign='top' style='width:66px; height:50px'>");
                sb.AppendFormat("<div class='contentEditableContainer contentImageEditable' style='width:66;Height:50'> <img src='http://www.npljobs.com/images/{0}' alt='' title='' width='66' height='50'></div>", lstJobs[i].CompanyImage);
                sb.Append("</td> <td valign='top' style='padding-left: 20px;'> <div class='contentEditableContainer contentTextEditable'>");
                sb.Append("<div class='contentEditable' dir='ltr' style='height: auto;'>");
                sb.AppendFormat("<h2 style='text-align: left;'><span style='color: rgb(79, 129, 189);'><a href='http://www.npljobs.com/JobSeeker/JobDetails.aspx?jID={0}' target='_blank'><span style='color: rgb(79, 129, 189); font-size: 12px;'><strong>{1}</strong></span></a></span></h2>", lstJobs[i].JobID.ToString(), lstJobs[i].JobTitle);
                sb.AppendFormat("<h2 style='text-align: left;'><strong><span style='font-family: Verdana, Arial, sans-serif; text-align: right; color: rgb(149, 55, 52); font-size: 11px; background-color: rgb(219, 238, 243);'>Deadline:- {0}</span></strong></h2>", lstJobs[i].ApplicationDateline.ToLongDateString());
                sb.AppendFormat("<p> <strong><span style='font-size: 12px;'><span style='color:#485C5A; font-family: Verdana, Arial, sans-serif; text-align: right;'>Company Name: {0} </span></span></strong><strong><span style='font-size: 10px;'><span data-redactor='verified' style='font-family: Georgia; color: rgb(68, 68, 68); text-align: right;'></span></span></strong></p>", lstJobs[i].CompanyName);
                sb.AppendFormat("<p> <strong><span style='font-size: 12px;'><span style='color:#485C5A; font-family: Verdana, Arial, sans-serif; text-align: right;'>Job Location: {0} </span></span></strong><strong><span style='font-size: 10px;'><span data-redactor='verified' style='font-family: Georgia; color: rgb(68, 68, 68); text-align: right;'></span></span></strong></p>", (lstJobs[i].Location != null ? "(Job Location: " + lstJobs[i].Location + ")" : "Any where"));
                sb.AppendFormat("<p> <strong><span style='font-size: 12px;'><span data-redactor='verified' style='font-family: Georgia; color:#485C5A; text-align: right;'></span></span></strong><span style='font-family: Georgia; color: rgb(68, 68, 68); text-align: right; font-size: 10px;'><strong>Salary Range: {0}</strong></span></p>", (lstJobs[i].SalaryRangeMin > 0 ? lstJobs[i].SalaryRangeMin.ToString() + "-" + lstJobs[i].SalaryRangeMax.ToString() : "Negotiable"));
                sb.AppendFormat("<p><span style='font-size: 12px;'>We are looking for a recent {0}…</span> <a href='http://www.npljobs.com/JobSeeker/JobDetails.aspx?jID={1}' style='font-size: 13px;'>More details</a></p>", lstJobs[i].JobTitle, lstJobs[i].JobID.ToString());
                sb.AppendFormat("<p style='text-align: justify;'><strong><span style='color: rgb(192, 80, 77);'>Skills:</span></strong> {0}</p>", lstJobs[i].Skills);
                //sb.Append(" <a href='http://mycareer.com.au/jobs/melbourne-cbd-3000-vic/it-telecommunications/web-development/9349178+graduate+developer+interested+in+c+or+c+net.aspx?from=jobalert&amp;alertid=1253468&amp;s_cid=ja:20140610:weekly:all:all:&amp;utm_source=jobalert&amp;utm_medium=email' style='font-size: 13px;'></a>");
                sb.Append("<p></p><p></p><p></p><p></p><p></p><p style='text-align: right;'></p>");
                sb.Append("</div></div></td></tr></tbody></table></div>");
                sb.Append("<div style='font-size: 0; padding-top: 10px; padding-bottom: 10px;'>");
                sb.Append("<img src='https://app.cakemail.com/editor_images2/image_c9b0ea15/campaigns/4235181/editor_images/image_d2e084b1/template1/line.png' width='540' height='2'></div>");
                sb.Append("</div>");
            }
            return sb.ToString();
        }

        private string PopulateBody(string userName, string skills, string jobList, string jobDetails, int TotalJobs, string ClientAddress, string unsubscribe)
        {
            string body = string.Empty;
            string url = ConfigurationManager.AppSettings["EMAIL_TEMPLATE"] != null ? ConfigurationManager.AppSettings["EMAIL_TEMPLATE"].ToString() : string.Empty;
            var uri = new Uri(url);

            var wc = new WebClient();
            using (var sourceStream = wc.OpenRead(uri.AbsoluteUri))
            {
                using (var reader = new StreamReader(sourceStream))
                {
                    body = reader.ReadToEnd();
                }
            }

            body = body.Replace("{CurrentDate}", System.DateTime.Now.ToLongDateString());
            body = body.Replace("{UserName}", userName);
            body = body.Replace("{JobList}", jobList);
            body = body.Replace("{JobDetails}", jobDetails);
            body = body.Replace("{Skills}", skills);
            body = body.Replace("{TotalJobs}", TotalJobs.ToString());
            body = body.Replace("{ClientAddress}", ClientAddress);
            body = body.Replace("{Unsubscribe}", unsubscribe);

            return body;
        }


        #endregion

        #region HasSpecifiedTimeElapsed
        /// <summary>
        /// This function checks whether or not the time specified in the config file 
        /// has been elapsed or not
        /// </summary>
        /// <param name="ts"></param>
        /// <returns></returns>
        private static bool HasSpecifiedTimeElapsed(DateTime ts, int frequencyID)
        {
            bool isTimeOver = true;

            Frequency e = (Frequency)frequencyID;

            if (e.Equals(Frequency.Daily))
            {
                double hours = (DateTime.Now - ts).TotalHours;
                isTimeOver = hours >= 24 ? true : false;
            }
            else if (e.Equals(Frequency.Weekly))
            {
                double totalDays = (DateTime.Now - ts).TotalDays;
                isTimeOver = totalDays >= 7 ? true : false;
            }
            else if (e.Equals(Frequency.Monthly))
            {
                double totalDays = (DateTime.Now - ts).TotalDays;
                isTimeOver = totalDays < 1 ? true : false;
            }

            return isTimeOver;
        }
        #endregion

    }
}

